<template>
<el-dialog title="执行监听器" :visible.sync="dialogVisible" width="900px" :before-close="handleClose"
		@closed="$emit('close')">
	<el-form ref="form" :model="formData" :rules="rules" >
		<el-tabs type="border-card" value="executionListenerTab">
			<el-tab-pane label="执行监听器" name="executionListenerTab">
				<el-row style="margin-bottom: 20px;">
						<el-button type="primary" size="medium" @click="addListener">新增</el-button>
				</el-row>
				<el-table border :data="formData.executionListener" style="width: 100%">
					<el-table-column prop="event" label="事件" align="center" >
						<template slot-scope="scope">
							<el-form-item :prop="'executionListener.'+scope.$index+'.event'" 
							:rules="rules.event" :class="col">
								<el-select v-model="scope.row.event">
									<el-option v-for="item in excutionEventTypes"
									:key="item.value"
									:label="item.label"
									:value="item.value"
									>
									</el-option>
								</el-select>
							</el-form-item>
						</template>
					</el-table-column>
					<el-table-column prop="type" label="类型"align="center" :render-header="showTip">
						<template slot-scope="scope">
							<el-form-item :prop="'executionListener.'+scope.$index+'.type'"
							:rules="rules.type" :class="col">
								<el-select v-model="scope.row.type">
									<el-option v-for="item in excutionTypes"
									:key="item.value"
									:label="item.label"
									:value="item.value"
									>
									</el-option>
								</el-select>
							</el-form-item>
						</template>
					</el-table-column>
					<el-table-column prop="className" label="java类名"align="center">
						<template slot-scope="scope">
							<el-form-item :prop="'executionListener.'+scope.$index+'.className'"
							:rules="rules.className" :class="col">
								<el-input v-model="scope.row.className" ></el-input>
							</el-form-item>
						</template>
					</el-table-column>
					<el-table-column prop="params" label="参数" width="85px" align="center" >
						<template slot-scope="scope">
							<el-form-item :class="col" >
								<el-badge :value="scope.row.params ? scope.row.params.length : 0">
								 <el-button size="small" @click="configParam(scope.$index)" >编辑</el-button>
								</el-badge>
							</el-form-item>
						</template>
					</el-table-column>
					<el-table-column label="操作" width="82px" align="center" :class="col">
						<template slot-scope="{row}">
							<el-button size="mini" icon="el-icon-delete" @click="deleteListener(row)"></el-button>
						</template>
					</el-table-column>
				</el-table>
				</el-tab-pane>
		</el-tabs>
	</el-form>
	<span slot="footer" class="dialog-footer">
		<el-button @click="dialogVisible = false">取 消</el-button>
		<el-button type="primary" @click="closeDialog">确 定</el-button>
		</span>
	<listenerParam v-if="showParamDialog" :value="formData.executionListener[nowIndex].params" @close="finishConfigParam" />
</el-dialog>
</template>
<script>
	 import listenerParam from './listenerParam'
	 import mixinPanel from '../../mixins/mixinPanel.js'
	export default {
		components:{listenerParam},
		mixins: [mixinPanel],
		data() {
			return {
				nowIndex:null,
				col:"col",
				dialogVisible: true,
				showParamDialog:false,
				formData:{
					executionListener:[]
				},
				excutionEventTypes: [
				    {value: 'start', label: 'start'},
				    {value: 'take', label: 'take'},
				    {value: 'end', label: 'end'}
				],
				excutionTypes:[
				  { label: '类', value: 'class' },
				  { label: '表达式', value: 'expression' },
				  { label: '委托表达式', value: 'delegateExpression' }
				],
				rules:{
					event:[{required: true, message: '请选择事件', trigger: 'change'}],
					type:[{required: true, message: '请选择事件', trigger: 'change'}],
					className:[{required: true, message: '请输入', trigger: 'blur'}]
				}
			};
		},
		mounted(){
			this.formData.executionListener = this.element.businessObject.extensionElements?.values
			  .filter(item => item.$type === 'flowable:ExecutionListener')
			  .map(item => {
			    let type
			    if ('class' in item) type = 'class'
			    if ('expression' in item) type = 'expression'
			    if ('delegateExpression' in item) type = 'delegateExpression'
			    return {
			      event: item.event,
			      type: type,
			      className: item[type],
			      params: item.fields?.map(field => {
			        let fieldType
			        if ('stringValue' in field) fieldType = 'stringValue'
			        if ('expression' in field) fieldType = 'expression'
			        return {
			          name: field.name,
			          type: fieldType,
			          value: field[fieldType]
			        }
			      }) ?? []
			    }
			  }) ?? []
		},
		methods: {
			showTip(h,{column}){
				const inReview = `类：示例 com.company.MyCustomListener，自定义类必须实现 org.flowable.engine.delegate.TaskListener 接口 <br />
								  表达式：示例 \${myObject.callMethod(task, task.eventName)} <br />
								  委托表达式：示例 \${myListenerSpringBean} ，该 springBean 需要实现 org.flowable.engine.delegate.TaskListener 接口`
				        return h(
				　　　　    'div', [
				                h('span', column.label),
				                h('el-tooltip', {
				                    props: {placement: 'top'},
									
				                }, [
				                    h('div', {
				                        slot: 'content',
				                        style: {
				                            'width':'650px',
				                            whiteSpace: 'normal',
				                            'margin-bottom': '10px'
				                        },
										domProps: {innerHTML:inReview}
				                    }),
				                    h('i', {
				                        class: 'el-icon-info',
				                        style: 'color:blue;margin-left:5px;'
				                    })
				                ],)
				            ]
				　　　　 )
			},
			deleteListener(row){
				let index = this.formData.executionListener.indexOf(row)
				this.formData.executionListener.splice(index, 1)
			},
			addListener(){
				let data = {
					event:undefined,
					type:undefined,
					className:undefined,
					params:undefined
				}
				this.formData.executionListener.push(data)
			},
			updateElement() {
			  if (this.formData.executionListener?.length) {
			    let extensionElements = this.element.businessObject.get('extensionElements')
			    if (!extensionElements) {
			      extensionElements = this.bpmnModel.get('moddle').create('bpmn:ExtensionElements')
			    }
			    // 清除旧值
			    extensionElements.values = extensionElements.values?.filter(item => item.$type !== 'flowable:ExecutionListener') ?? []
			    this.formData.executionListener.forEach(item => {
			      const executionListener = this.bpmnModel.get('moddle').create('flowable:ExecutionListener')
			      executionListener['event'] = item.event
			      executionListener[item.type] = item.className
			      if (item.params && item.params.length) {
			        item.params.forEach(field => {
			          const fieldElement = this.bpmnModel.get('moddle').create('flowable:Field')
			          fieldElement['name'] = field.name
			          fieldElement[field.type] = field.value
			          // 注意：flowable.json 中定义的string和expression类为小写，不然会和原生的String类冲突，此处为hack
			          // const valueElement = this.bpmnModel.get('moddle').create(`flowable:${field.type}`, { body: field.value })
			          // fieldElement[field.type] = valueElement
			          executionListener.get('fields').push(fieldElement)
			        })
			      }
			      extensionElements.get('values').push(executionListener)
			    })
			    this.updateProperties({ extensionElements: extensionElements })
			  } else {
			    const extensionElements = this.element.businessObject[`extensionElements`]
			    if (extensionElements) {
			      extensionElements.values = extensionElements.values?.filter(item => item.$type !== 'flowable:ExecutionListener') ?? []
			    }
			  }
			},
			closeDialog(){
				this.$refs['form'].validate((validate)=>{
					if(validate){
						this.updateElement()
						this.dialogVisible = false
					}
				})
			},
			handleClose(done) {
				this.$confirm('确认关闭？')
					.then(_ => {
						done();
					})
					.catch(_ => {});
			},
			finishConfigParam(param) {
			  this.showParamDialog = false
			  // hack 数量不更新问题
			  const cache = this.formData.executionListener[this.nowIndex]
			  cache.params = param
			  this.$set(this.formData.executionListener[this.nowIndex], this.nowIndex, cache)
			  this.nowIndex = null
			},
			configParam(index) {
			  this.nowIndex = index
			  const nowObj = this.formData.executionListener[index]
			  if (!nowObj.params) {
			    nowObj.params = []
			  }
			  this.showParamDialog = true
			},
		}
	};
</script>

<style >
	.col{
		height: 50px;
		margin-top: 10px;
		/* margin-right: 40px; */
	}
</style>
